﻿namespace Cellfish.Toolbox.Facts.Linq
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;

    using Cellfish.Test;
    using Cellfish.Toolbox.Linq;

    using Microsoft.VisualStudio.TestTools.UnitTesting;

    [TestClass]
    public class HydrateExtensionsFacts
    {
        [TestInitialize]
        public void Setup()
        {
            IEnumerable<int> enumerable = new DummyEnumerable(11);
            Assert.AreEqual(11, enumerable.Count(), "First enumeration of dummy should return items.");
            Assert.AreEqual(0, enumerable.Count(), "Second enumeration of dummy should not return items.");
        }

        [TestMethod]
        public void Given_null_enumerable_When_hydrating_Then_ArgumentNullException_is_thrown()
        {
            IEnumerable<int> source = null;
            Ensure.Throws<ArgumentNullException>(() => source.Hydrate());
        }

        [TestMethod]
        public void Given_enumerable_that_can_only_enumerated_once_When_hydrating_Then_result_can_be_enumerated_twice()
        {
            IEnumerable<int> source = new DummyEnumerable(42);
            var actual = source.Hydrate();
            Assert.AreEqual(42, actual.Count(), "First enumeration of dummy should return items.");
            Assert.AreEqual(42, actual.Count(), "Second enumeration of dummy should return items.");
        }

        private class DummyEnumerable : IEnumerable<int>
        {
            private int nextValue;

            public DummyEnumerable(int items)
            {
                this.nextValue = items;
            }

            IEnumerator<int> IEnumerable<int>.GetEnumerator()
            {
                while (this.nextValue > 0)
                {
                    yield return this.nextValue--;
                }
            }

            IEnumerator IEnumerable.GetEnumerator()
            {
                throw new NotImplementedException();
            }
        }
    }
}
